<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Using a Credentials Provider</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/credentials-provider" />
  <meta property="og:title" content="Quarkus - Using a Credentials Provider" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/credentials-provider">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Using a Credentials Provider</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#vault-credentials-provider">Vault Credentials Provider</a></li>
<li><a href="#custom-credentials-provider">Custom Credentials Provider</a></li>
<li><a href="#new-credentials-provider-extension">New Credentials Provider extension</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Interacting with a datastore typically implies first connecting using credentials.
Those credentials will allow the client to be identified, authenticated and eventually authorized.
Username/password based authentication is very common, but that is not by any means the only one.
Such credentials information may appear in the application configuration,
but it is becoming increasingly popular to store this type of sensitive information in secure stores,
such as HashiCorp Vault, Azure Key Vault or the AWS Secrets Manager to name just a few.</p>
</div>
<div class="paragraph">
<p>To bridge datastores that consume credentials, which can take different forms,
and secure stores that provide those credentials,
Quarkus introduces an intermediate abstraction called <code>Credentials Provider</code>,
that some extensions may support to consume credentials (e.g. <code>agroal</code>),
and some others may implement to produce credentials (e.g. <code>vault</code>).</p>
</div>
<div class="paragraph">
<p>This Service Programming Interface (SPI) may also be used by implementers that want to support custom providers
not yet implemented in Quarkus (e.g. Azure Key Vault).</p>
</div>
<div class="paragraph">
<p>Currently, the <code>Credentials Provider</code> interface is implemented by the <code>vault</code> extension, and is supported
by the following credentials consumer extensions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>agroal</code></p>
</li>
<li>
<p><code>reactive-db2-client</code></p>
</li>
<li>
<p><code>reactive-mysql-client</code></p>
</li>
<li>
<p><code>reactive-pg-client</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>All extensions that rely on username/password authentication also allow setting configuration
properties in the <code>application.properties</code> as an alternative. But the <code>Credentials Provider</code> is the only option
if credentials are generated (e.g. <code>Vault Dynamic DB Credentials</code>) or if a custom credentials provider is required.</p>
</div>
<div class="paragraph">
<p>This guide will show how to use the <code>Credentials Provider</code> provided in the <code>vault</code> extension,
then we will look at implementing a custom <code>Credentials Provider</code>, and finally we will talk about additional
considerations regarding implementing a <code>Credentials Provider</code> in a new extension.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This technology is considered preview.</p>
</div>
<div class="paragraph">
<p>In <em>preview</em>, backward compatibility and presence in the ecosystem is not guaranteed.
Specific improvements might require to change configuration or APIs and plans to become <em>stable</em> are under way.
Feedback is welcome on our <a href="https://groups.google.com/d/forum/quarkus-dev">mailing list</a> or as issues in our <a href="https://github.com/quarkusio/quarkus/issues">GitHub issue tracker</a>.</p>
</div>
<div class="paragraph">
<p>For a full list of possible extension statuses, check our <a href="https://quarkus.io/faq/#extension-status">FAQ entry</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>roughly 20 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
<li>
<p>Docker installed</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault-credentials-provider"><a class="anchor" href="#vault-credentials-provider"></a>Vault Credentials Provider</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To configure a <code>Vault Credentials Provider</code> you need to provide the following properties:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.vault.credentials-provider.&lt;name&gt;.&lt;property&gt;=&lt;value&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>&lt;name&gt;</code> will be used in the consumer to refer to this provider. The <code>&lt;property&gt;</code> and <code>&lt;value&gt;</code> fields are specific to the <code>Vault Credentials Provider</code>. For complete details, please refer to the <a href="vault-datasource">Vault Datasource guide</a>.</p>
</div>
<div class="paragraph">
<p>For instance:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.vault.credentials-provider.mydatabase.kv-path=myapps/vault-quickstart/db</code></pre>
</div>
</div>
<div class="paragraph">
<p>Once defined, the <code>mydatabase</code> provider can be used in any extension that supports the <code>Credentials Provider</code> interface. For instance in <code>agroal</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs"># configure your datasource
quarkus.datasource.db-kind = postgresql
quarkus.datasource.username = sarah
quarkus.datasource.credentials-provider = mydatabase
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/mydatabase</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that <code>quarkus.datasource.username</code> is the original <code>agroal</code> property, whereas the <code>password</code> property
is not included because the value will come from the <code>mydatabase</code> credentials provider we just defined.
An alternative is to define both username and password in Vault and drop the <code>quarkus.datasource.username</code>
property from configuration. All consuming extensions do support the ability to fetch both the username
and password from the provider, or just the password.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="custom-credentials-provider"><a class="anchor" href="#custom-credentials-provider"></a>Custom Credentials Provider</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Implementing a custom credentials provider is the only option when a vault product is not yet supported in Quarkus, or if credentials need to be retrieved from a custom store.</p>
</div>
<div class="paragraph">
<p>The only interface to implement is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public interface CredentialsProvider {

    String USER_PROPERTY_NAME = "user";
    String PASSWORD_PROPERTY_NAME = "password";

    Map&lt;String, String&gt; getCredentials(String credentialsProviderName);

}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>USER_PROPERTY_NAME</code> and <code>PASSWORD_PROPERTY_NAME</code> are standard properties that should be recognized by any consuming extension that support username/password based authentication.</p>
</div>
<div class="paragraph">
<p>It is required that implementations be valid <code>@ApplicationScoped</code> CDI beans.</p>
</div>
<div class="paragraph">
<p>Here is a simple example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@ApplicationScoped
@Unremovable
public class MyCredentialsProvider implements CredentialsProvider {

	@Override
	public Map&lt;String, String&gt; getCredentials(String credentialsProviderName) {

		Map&lt;String, String&gt; properties = new HashMap&lt;&gt;();
		properties.put(USER_PROPERTY_NAME, "hibernate_orm_test");
		properties.put(PASSWORD_PROPERTY_NAME, "hibernate_orm_test");
		return properties;
	}

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that we decided here to return both the username and the password.</p>
</div>
<div class="paragraph">
<p>This provider may be used in a datasource definition like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.datasource.db-kind=postgresql
quarkus.datasource.credentials-provider=custom
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5431/hibernate_orm_test</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to pass configuration properties to the provider using standard MicroProfile Config injection:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">custom.foo=bar</code></pre>
</div>
</div>
<div class="paragraph">
<p>And in the provider implementation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Inject
Config config;

@Override
public Map&lt;String, String&gt; getCredentials(String credentialsProviderName) {

    System.out.println("MyCredentialsProvider called with foo=" + config.getValue(credentialsProviderName + ".foo", String.class));
    ...</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="new-credentials-provider-extension"><a class="anchor" href="#new-credentials-provider-extension"></a>New Credentials Provider extension</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When creating a custom credentials provider in a new extension, there are a few additional considerations.</p>
</div>
<div class="paragraph">
<p>First, you need to name it to avoid collisions in case multiple credentials providers are available in the project:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@ApplicationScoped
@Unremovable
@Named("my-credentials-provider")
public class MyCredentialsProvider implements CredentialsProvider {</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is the responsibility of the consumer to allow a <code>credentials-provider-name</code> property:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.datasource.credentials-provider = custom
quarkus.datasource.credentials-provider-name = my-credentials-provider</code></pre>
</div>
</div>
<div class="paragraph">
<p>The extension should allow runtime config, such as the <code>CredentialsProviderConfig</code> from the <code>vault</code> extension
to configure any custom property in the provider. For an AWS Secrets Manager extension, this could be:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>region</code></p>
</li>
<li>
<p><code>credentials-type</code></p>
</li>
<li>
<p><code>secrets-id</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Note also that some consumers such as <code>agroal</code> will add to their connection configuration any properties returned
by the credentials provider, not just the username and password. So when you design the new credentials provider
limit the properties to what would be understood by consumers, or provide appropriate configuration options to
support different modes.</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
